﻿Imports System.Linq
Imports log4net
Imports Equipment.DataAccess

Public Class NotificationManager

    Private Shared logger As ILog = LogManager.GetLogger(GetType(NotificationManager))

#Region "Public Section"

    Public Shared Sub CreateNotificationsByTrigger(ByVal trigger As NotificationTrigger, ByVal name As String, Optional ByVal obj As Object = Nothing)

        Dim notifications = Notification.RetrieveAllByTrigger(trigger)

        For Each notification In notifications
            For Each userPreference In notification.Preferences
                If UserHasAccessForNotification(userPreference.User, notification, obj) Then
                    Try
                        If userPreference.Immediately Then
                            CreateNotificationEmail(userPreference.User, notification.NotificationTrigger, name)
                        ElseIf userPreference.OnSelectedDay Then
                            AddToWaitingList(userPreference, name)
                        End If
                    Catch ex As Exception
                        logger.ErrorFormat("Cannot create notification. {0}:{1}", ex.Message, ex.StackTrace)
                    End Try
                End If
            Next
        Next
    End Sub

#End Region

#Region "Private Section"
    Private Shared Function UserHasAccessForNotification(ByVal forUser As User, ByVal userNotification As Notification, ByVal obj As Object) As Boolean
        Dim result As Boolean = True
        Dim uInfo As New UserInfo(forUser)


        Select Case userNotification.NotificationTrigger
            Case NotificationTrigger.Asset_Modify, NotificationTrigger.Asset_Create
                Dim currAsset As Asset = DirectCast(obj, Asset)
                result = (uInfo.HasPermissionFor(PageType.AssetMaintain) Or uInfo.HasPermissionFor(PageType.AssetCreate)) AndAlso _
                    currAsset.HasAccessForGroups(uInfo.GroupIDs) Or uInfo.IsSuperUser
            Case NotificationTrigger.Notification_Create, NotificationTrigger.Notification_Modify
                result = uInfo.HasPermissionFor(PageType.NotificationType)
            Case NotificationTrigger.Requirement_Create, NotificationTrigger.Requirement_Modify
                result = uInfo.HasPermissionFor(PageType.BasicRequirementsSetup)
            Case NotificationTrigger.User_Create, NotificationTrigger.User_Modify
                Dim currUser As User = DirectCast(obj, User)
                result = uInfo.HasPermissionFor(PageType.Users) AndAlso (currUser.SiteID = uInfo.SiteID Or uInfo.IsSuperUser)
            Case NotificationTrigger.UserRole_Create, NotificationTrigger.UserRole_Modify
                Dim currRole As Role = DirectCast(obj, Role)
                result = uInfo.HasPermissionFor(PageType.UserRole) AndAlso (currRole.SiteID = uInfo.SiteID Or uInfo.IsSuperUser)
            Case NotificationTrigger.UserGroup_Create, NotificationTrigger.UserGroup_Modify
                Dim currGroup As Group = DirectCast(obj, Group)
                result = uInfo.HasPermissionFor(PageType.UserGroup) AndAlso (currGroup.SiteID = uInfo.SiteID Or uInfo.IsSuperUser)
            Case NotificationTrigger.Holiday_Create, NotificationTrigger.Holiday_Modify
                result = uInfo.HasPermissionFor(PageType.HolidayDefinition)
            Case NotificationTrigger.DepartmentSetup_CreateSite, NotificationTrigger.DepartmentSetup_ModifySite, _
                    NotificationTrigger.DepartmentSetup_CreateDepartment, NotificationTrigger.DepartmentSetup_ModifyDepartment
                result = uInfo.HasPermissionFor(PageType.SitesDepartmentSetup)
            Case NotificationTrigger.AssetStatus_Create, NotificationTrigger.AssetStatus_Modify, _
                    NotificationTrigger.AssetType_Create, NotificationTrigger.AssetType_Modify, _
                        NotificationTrigger.AssetCustomField_Create, NotificationTrigger.AssetCustomField_ModifyMandatoryFlag, _
                            NotificationTrigger.AssetCustomField_Modify
                result = uInfo.HasPermissionFor(PageType.AssetType)
            Case NotificationTrigger.WorkOrder_Create, NotificationTrigger.WorkOrder_Calibrate, NotificationTrigger.WorkOrder_AutomaticCreate, _
                    NotificationTrigger.WorkOrder_AdhocCreate, NotificationTrigger.WorkOrder_Overdue_ByDay, NotificationTrigger.WorkOrder_Overdue_ByHour, NotificationTrigger.WorkOrder_StatusChange
                Dim wo As WorkOrder = DirectCast(obj, WorkOrder)
                Dim hasAccessToWO As Boolean = False
                result = (uInfo.HasPermissionFor(PageType.CreateWorkOrder) Or uInfo.HasPermissionFor(PageType.ManageWorkOrder) _
                            Or uInfo.HasPermissionFor(PageType.ReviewWorkOrder) Or uInfo.HasPermissionFor(PageType.EditWorkOrder)) _
                                AndAlso HasAccesFoWorkOrder(wo, uInfo)
        End Select

        Return result
    End Function

    Private Shared Function HasAccesFoWorkOrder(ByVal wo As WorkOrder, ByVal uInfo As UserInfo) As Boolean

        If uInfo.IsSuperUser Then Return True

        If uInfo.IsSiteAdmin AndAlso wo.Asset.SiteDepartment.ParentID = uInfo.SiteID Then Return True

        If wo.WorkOrderGroups.Select(Function(g) g.GroupID).Count(Function(gID) uInfo.GroupIDs.Contains(gID)) > 0 Then Return True

        Return False
    End Function

    Private Shared Sub CreateNotificationEmail(ByVal notificationToSend As UserNotificationEmail)
        CreateNotificationEmail(notificationToSend.User, notificationToSend.Notification.NotificationTrigger, notificationToSend.EntityName)
    End Sub

    Private Shared Sub CreateNotificationEmail(ByVal toUser As User, ByVal trigger As NotificationTrigger, ByVal name As String)
        Dim messageMainContent As String = String.Empty
        Select Case trigger
            Case NotificationTrigger.Asset_Modify
                messageMainContent = String.Format("Asset '{0}' was updated.", name)
            Case NotificationTrigger.Asset_Create
                messageMainContent = String.Format("Asset '{0}' was created.", name)
            Case NotificationTrigger.Notification_Create
                messageMainContent = String.Format("Notification '{0}' was created.", name)
            Case NotificationTrigger.Notification_Modify
                messageMainContent = String.Format("Notification '{0}' was updated.", name)
            Case NotificationTrigger.Requirement_Create
                messageMainContent = String.Format("Basic Requirement '{0}' was created.", name)
            Case NotificationTrigger.Requirement_Modify
                messageMainContent = String.Format("Basic Requirement '{0}' was updated.", name)
            Case NotificationTrigger.User_Create
                messageMainContent = String.Format("User '{0}' was created.", name)
            Case NotificationTrigger.User_Modify
                messageMainContent = String.Format("User '{0}' was updated.", name)
            Case NotificationTrigger.UserRole_Create
                messageMainContent = String.Format("User Role '{0}' was created.", name)
            Case NotificationTrigger.UserRole_Modify
                messageMainContent = String.Format("User Role '{0}' was updated.", name)
            Case NotificationTrigger.UserGroup_Create
                messageMainContent = String.Format("User Group '{0}' was created.", name)
            Case NotificationTrigger.UserGroup_Modify
                messageMainContent = String.Format("User Group '{0}' was updated.", name)
            Case NotificationTrigger.Holiday_Create
                messageMainContent = String.Format("Holiday '{0}' was created.", name)
            Case NotificationTrigger.Holiday_Modify
                messageMainContent = String.Format("Holiday '{0}' was updated.", name)
            Case NotificationTrigger.DepartmentSetup_CreateSite
                messageMainContent = String.Format("Site '{0}' was created.", name)
            Case NotificationTrigger.DepartmentSetup_ModifySite
                messageMainContent = String.Format("Site '{0}' was updated.", name)
            Case NotificationTrigger.DepartmentSetup_CreateDepartment
                messageMainContent = String.Format("Department '{0}' was created.", name)
            Case NotificationTrigger.DepartmentSetup_ModifyDepartment
                messageMainContent = String.Format("Department '{0}' was updated.", name)
            Case NotificationTrigger.AssetStatus_Create
                messageMainContent = String.Format("Asset Status '{0}' was created.", name)
            Case NotificationTrigger.AssetStatus_Modify
                messageMainContent = String.Format("Asset Status '{0}' was updated.", name)
            Case NotificationTrigger.AssetType_Create
                messageMainContent = String.Format("Asset Type '{0}' was created.", name)
            Case NotificationTrigger.AssetType_Modify
                messageMainContent = String.Format("Asset Type '{0}' was updated.", name)
            Case NotificationTrigger.AssetCustomField_Create
                messageMainContent = String.Format("Asset Custom Field '{0}' was created.", name)
            Case NotificationTrigger.AssetCustomField_Modify
                messageMainContent = String.Format("Asset Custom Field '{0}' was updated.", name)
            Case NotificationTrigger.AssetCustomField_ModifyMandatoryFlag
                messageMainContent = String.Format("Mandatory flag for predefined field '{0}' was changed.", name)
            Case NotificationTrigger.WorkOrder_Create
                messageMainContent = String.Format("Work Order '{0}' was created.", name)
            Case NotificationTrigger.WorkOrder_Calibrate
                messageMainContent = String.Format("Work Order '{0}' was updated.", name)
            Case NotificationTrigger.WorkOrder_AutomaticCreate
                messageMainContent = String.Format("Work Order '{0}' was created automatically.", name)
            Case NotificationTrigger.WorkOrder_AdhocCreate
                messageMainContent = String.Format("Adhoc Work Order '{0}' was created.", name)
            Case NotificationTrigger.WorkOrder_Overdue_ByDay
            Case NotificationTrigger.WorkOrder_Overdue_ByHour
                messageMainContent = String.Format("Work Order '{0}' status was changed.", name)
        End Select

        Dim message As String = String.Format("Dear {0},{2}{2}We are happy to notify you that {1}.{2}{2}{2} Best Regards.{2} Equipment Support.", toUser.FullName, messageMainContent, ControlChars.NewLine)

        EmailManager.SendEmail(toUser.Email, message)
    End Sub

    Private Shared Sub AddToWaitingList(ByVal userPreference As Preference, ByVal name As String)
        Dim tillDate As DateTime

        If DateTime.Today.DayOfWeek < userPreference.User.PreferenceDay Then
            tillDate = DateTime.Today.AddDays(userPreference.User.PreferenceDay - DateTime.Today.DayOfWeek - 1)
        Else
            tillDate = DateTime.Today.AddDays(6 - (DateTime.Today.DayOfWeek - userPreference.User.PreferenceDay))
        End If

        UserNotificationEmail.Insert(userPreference.User, userPreference.NotificationID, name, tillDate)
    End Sub

    Public Shared Sub SendNotificationBySchedule()

        Dim notifications = Notification.RetrieveAllByTrigger(NotificationTrigger.WorkOrder_Overdue_ByDay)


        If notifications.Count > 0 Then

            For Each notification In notifications

                Dim dueDateFrom As DateTime = DateTime.Today
                Dim dueDateTo As DateTime = DateTime.Now

                'If notification.OverdueType = NotificationOverdueType.XDaysBeforeOverdue Then
                '    dueDateTo = DateTime.Now.AddDays(notification.OverdueXValue)
                'ElseIf notification.OverdueType = NotificationOverdueType.XHoursBeforeOverdue Then
                '    dueDateTo = DateTime.Now.AddHours(notification.OverdueXValue)
                'Else
                '    dueDateFrom = DateTime.Today.AddYears(-5)
                '    dueDateTo = DateTime.Now.AddDays(-notification.OverdueXValue)
                'End If

                Dim notCalibratedWorkOrderList = WorkOrder.RetrieveAllByStatuses(WorkOrderStatusType.AutoCreated, _
                                                                                    WorkOrderStatusType.ManuallyCreated, _
                                                                                        dueDateFrom, dueDateTo)
                'For Each woItem In notCalibratedWorkOrderList
                '    Dim lastComletion = woItem.GetLastCompletedNotification()
                '    If lastComletion Is Nothing Then
                '        CreateNotificationByPreferenceAndWorkOrder(notification, woItem)
                '        notification.MarkAsCompletedForWorkOrder(woItem)
                '    ElseIf notification.OverdueType = NotificationOverdueType.XHoursBeforeOverdue AndAlso _
                '        lastComletion.CompletedDate < DateTime.Now.AddDays(-notification.OverdueXValue) Then
                '        CreateNotificationByPreferenceAndWorkOrder(notification, woItem)
                '        notification.MarkAsCompletedForWorkOrder(woItem)
                '    End If
                'Next
            Next
        End If

        Dim notificationEmails = UserNotificationEmail.RetrieveAllByDate(DateTime.UtcNow.Date)
        For Each notificationEmailToSend In notificationEmails
            CreateNotificationEmail(notificationEmailToSend)
            notificationEmailToSend.Delete()
        Next
    End Sub

    Private Shared Sub CreateNotificationByPreferenceAndWorkOrder(ByVal notification As Notification, ByVal wo As WorkOrder)
        For Each userPreference In notification.Preferences
            If userPreference.Immediately Then
                CreateNotificationEmail(userPreference.User, notification.NotificationTrigger, wo.ID)
            ElseIf userPreference.OnSelectedDay Then
                AddToWaitingList(userPreference, wo.ID)
            End If
        Next
    End Sub
#End Region

End Class
